package design.graduation.novelsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import design.graduation.novelsystem.constant.Constant;
import design.graduation.novelsystem.fastdfs.UploadUtil;
import design.graduation.novelsystem.mapper.AdminMapper;
import design.graduation.novelsystem.model.domian.Admin;
import design.graduation.novelsystem.model.domian.AdminLoginLog;
import design.graduation.novelsystem.model.dto.ActiveAdmin;
import design.graduation.novelsystem.model.dto.DataGridView;
import design.graduation.novelsystem.model.vo.AdminVo;
import design.graduation.novelsystem.service.AdminLoginLogService;
import design.graduation.novelsystem.service.AdminService;
import design.graduation.novelsystem.util.MD5Utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: 洪少尉
 * @Date: 2020/4/13 23:41
 * @Description: 
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService{
	@Autowired
	private AdminLoginLogService adminLoginLogService;
	@Autowired
	private UploadUtil uploadUtil;
	/**
	 * 后台管理登录
	 * @param loginName 登录名
	 * @param password 登录密码
	 * @param request 请求信息
	 * @return token和管理员名称
	 */
	@Override
	public Map<String,String> doLogin(String loginName, String password, HttpServletRequest request) {
		/*
		 *使用Shiro编写认证操作
		 */
		//1.获取Subject
		Subject subject = SecurityUtils.getSubject();
		//2.封装用户数据
		UsernamePasswordToken loginToken = new UsernamePasswordToken(loginName,password);
		//登录
		subject.login(loginToken);
		//获取token
		String token = subject.getSession().getId().toString();
		//从登录状态中，获取管理员信息
		ActiveAdmin activeAdmin= (ActiveAdmin) subject.getPrincipal();
		AdminLoginLog adminLoginLog = new AdminLoginLog();
		adminLoginLog.setName(activeAdmin.getAdmin().getName())
				.setLoginName(activeAdmin.getAdmin().getLoginName())
				.setLoginIp(request.getRemoteAddr())
				.setLoginTime(new Date());
		//保存管理员登录日志
		this.adminLoginLogService.save(adminLoginLog);
		Map<String,String> adminInfo  = new HashMap<>();
		adminInfo.put("TOKEN",token);
		adminInfo.put("Name",activeAdmin.getAdmin().getName());
		return adminInfo;
	}
	/**
	 * 通过登录名查找管理员
	 * @param loginName 登录名
	 * @return 当前管理员
	 */
	@Override
	public Admin findByUserName(String loginName) {
		QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq(Admin.COL_LOGIN_NAME,loginName);
		return this.baseMapper.selectOne(queryWrapper);
	}

	/**
	 * 查询管理员表单数据
	 *
	 * @param adminVo 查询条件
	 * @return 管理员表单数据
	 */
	@Override
	public DataGridView queryAllAdmin(AdminVo adminVo) {
		QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq(Admin.COL_TYPE, Constant.USER_TYPE_NORMAL)
				.like(StringUtils.isNotBlank(adminVo.getName()),Admin.COL_NAME,adminVo.getName())
				.like(StringUtils.isNotBlank(adminVo.getRemark()),Admin.COL_REMARK,adminVo.getRemark())
				.ge(adminVo.getStartTime()!=null,Admin.COL_CREATE_TIME,adminVo.getStartTime())
				.le(adminVo.getEndTime()!=null,Admin.COL_EDIT_TIME,adminVo.getEndTime())
				.orderByDesc(Admin.COL_SORT_CODE);
		IPage<Admin> page = new Page<>();
		this.baseMapper.selectPage(page,queryWrapper);
		return new DataGridView(page.getTotal(),page.getRecords());
	}

	/**
	 * 添加管理员
	 *
	 * @param admin 管理员信息
	 * @return true/false
	 */
	@Override
	public boolean saveAdmin(Admin admin) {
		admin.setCreateTime(new Date())
				.setEditTime(new Date())
				.setAvailable(Constant.AVAILABLE_TRUE)
				.setHeadImagePath(Constant.DEFAULT_HEAD_IMAGE_PATH)
				.setSalt(MD5Utils.createSalt())
				.setType(Constant.USER_TYPE_NORMAL);
		admin.setPassword(MD5Utils.md5(Constant.DEFAULT_PASSWORD,admin.getSalt(),Constant.DEFAULT_HASHITERATIONS));
		return this.save(admin);
	}

	/**
	 * 更新管理员信息
	 *
	 * @param admin 管理员信息
	 * @return true/false
	 */
	@Override
	public boolean updateAdmin(Admin admin) {
		//若传入密码不为空，则更新密码
		if (StringUtils.isNotBlank(admin.getPassword())){
			ActiveAdmin activeAdmin= (ActiveAdmin) SecurityUtils.getSubject().getPrincipal();
			admin.setSalt(MD5Utils.createSalt())
					.setId(activeAdmin.getAdmin().getId());
			admin.setPassword(MD5Utils.md5(admin.getPassword(),admin.getSalt(),Constant.DEFAULT_HASHITERATIONS));
		}
		admin.setEditTime(new Date());
		return this.updateById(admin);
	}

	/**
	 * 重置管理员密码
	 *
	 * @param id 管理员id
	 * @return true/false
	 */
	@Override
	public boolean resetAdminPassword(Integer id) {
		Admin admin = new Admin();
		admin.setSalt(MD5Utils.createSalt());
		admin.setId(id)
				.setEditTime(new Date())
				.setPassword(MD5Utils.md5(Constant.DEFAULT_PASSWORD,admin.getSalt(),Constant.DEFAULT_HASHITERATIONS));
		return this.updateById(admin);
	}

	/**
	 * 保存管理员和角色之间的关系
	 *
	 * @param aid  管理员id
	 * @param rids 角色id集合
	 * @return true/false
	 */
	@Override
	public boolean saveAdminRole(Integer aid, Integer[] rids) {
		//根据用户ID删除角色和用户中间表的数据
		boolean flag = this.baseMapper.deleteRolesByAid(aid);
		if(null!=rids&&rids.length>0){
			for (Integer rid : rids) {
				flag = this.baseMapper.saveAdminRole(aid,rid);
			}
		}
		this.updateById(new Admin(aid,new Date()));
		return flag;
	}

	/**
	 * 当前管理员排序码的最大值
	 *
	 * @return Integer
	 */
	@Override
	public Integer queryAdminMaxSortCode() {
		return this.baseMapper.getAdminMaxSortCode();
	}

	/**
	 * 通过管理员id删除管理员
	 *
	 * @param id 管理员id
	 * @return boolean
	 */
	@Override
	public boolean removeAdminById(Integer id) {
		//根据用户ID删除角色和用户中间表的数据
		this.baseMapper.deleteRolesByAid(id);
		return this.removeById(id);
	}

	/**
	 * 上传用户头像，更新数据库
	 *
	 * @param mf 头像
	 * @return Map<String, String>
	 */
	@Override
	public Map<String, String> updateAdminHeadImage(MultipartFile mf) {
		String path = uploadUtil.uploadImage(mf);
		Map<String,String> map=new HashMap<>();
		map.put("src",path);
		//更新数据库
		ActiveAdmin activeAdmin= (ActiveAdmin) SecurityUtils.getSubject().getPrincipal();
		Admin admin = activeAdmin.getAdmin();
		admin.setHeadImagePath(path)
				.setEditTime(new Date());
		this.updateById(admin);
		return map;
	}

	/**
	 * 判断当前密码
	 *
	 * @param password 管理员原密码
	 * @return boolean
	 */
	@Override
	public boolean checkPassword(String password) {
		ActiveAdmin activeAdmin= (ActiveAdmin) SecurityUtils.getSubject().getPrincipal();
		Admin admin = this.baseMapper.selectById(activeAdmin.getAdmin().getId());
		return admin.getPassword().equals(MD5Utils.md5(password, admin.getSalt(), Constant.DEFAULT_HASHITERATIONS));
	}
}
